/**
 * 从 Angular 核心库中导入 Component 符号
 */
import { Component, OnInit } from '@angular/core';

/**
 * 导入Hero 类
 */
import { Hero } from '../hero';
// import { HEROES} from '../mock-heroes';
import { HeroService } from '../hero.service';

/**
 * 为组件类加上 @Component 装饰器。
 * @Component 是个装饰器函数，
 * 用于为该组件指定 Angular 所需的元数据。
 * CLI 自动生成了三个元数据属性：
 *  1)selector— 组件的选择器（CSS 元素选择器）, 用来在父组件的模板中匹配 HTML 元素的名称，以识别出该组件。
 *  2)templateUrl— 组件模板文件的位置。
 *  3)styleUrls— 组件私有 CSS 样式表文件的位置。
 */
@Component ({
  selector: 'app-heroes',
  templateUrl: './heroes.component.html',
  styleUrls: ['./heroes.component.css']
})
/**
 * 始终要 export 这个组件类，以便在其它地方（比如 AppModule）导入它。
 */
export class HeroesComponent implements OnInit {
  /**
   * 属性
   */
  // hero = 'Windstorm';
  // hero: Hero = {
  //   id: 1,
  //   name: 'Windstorm'
  // };
  hero: Hero;
  // heroes = HEROES;
  heroes: Hero[];

  /**
   * 往构造函数中添加一个私有的 heroService，其类型为 HeroService。
   *
   * 这个参数同时做了两件事：
   * 1. 声明了一个私有 heroService 属性，
   * 2. 把它标记为一个 HeroService 的注入点。
   *
   * 当 Angular 创建 HeroesComponent 时，
   * 依赖注入系统就会把这个 heroService 参数设置为 HeroService 的单例对象。
   * @param hereService
   */
  constructor(private heroService: HeroService ) { }

  /**
   * ngOnInit 是一个生命周期钩子，
   * Angular 在创建完组件后很快就会调用 ngOnInit。
   * 这里是放置初始化逻辑的好地方。
   *
   * 你固然可以在构造函数中调用 setHeroes()，但那不是最佳实践。
   *
   * 让构造函数保持简单，只做初始化操作，
   * 比如把构造函数的参数赋值给属性。
   * 构造函数不应该做任何事。
   * 它肯定不能调用某个函数来向远端服务（比如真实的数据服务）发起 HTTP 请求。
   *
   * 而是选择在 ngOnInit 生命周期钩子中调用 getHeroes()，
   */
  ngOnInit() {
    this.setHeroes();
  }

  /**
   * 创建一个函数，以从服务中获取这些英雄数据。
   */
  setHeroes(): void {
    // this.heroes = this.hereService.getHeroes();
    this.heroService.getHeroes().subscribe(heroes => this.heroes = heroes);
  }

  /**
   * 当指定的名字非空时，
   * 这个处理器会用这个名字创建一个类似于 Hero 的对象（只缺少 id 属性），
   * 并把它传给服务的 addHero() 方法。
   * 当 addHero 保存成功时，
   * subscribe 的回调函数会收到这个新英雄，
   * 并把它追加到 heroes 列表中以供显示。
   * @param name
   */
  add(name: string): void {
    name = name.trim();
    if (!name) { return; }
    this.heroService.addHero({ name } as Hero)
      .subscribe(hero => {
        this.heroes.push(hero);
      });
  }

  /**
   *  组件的 delete() 方法会在 HeroService 对服务器的操作成功之前，
   *  先从列表中移除要删除的英雄。
   * @param hero
   */
  delete(hero: Hero): void {
    this.heroes = this.heroes.filter(h => h !== hero);
    /**
     * 如果你忘了调用 subscribe()，
     * 本服务将不会把这个删除请求发送给服务器。
     * 作为一条通用的规则，Observable 在有人订阅之前什么都不会做。
     */
    this.heroService.deleteHero(hero).subscribe();
  }

  // onSelect(tmp: Hero): void {
  //   this.hero = tmp;
  // }
}
